package com.heima.wemedia.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.heima.client.article.IArticleClient;
import com.heima.model.common.dtos.*;
import com.heima.model.common.pojos.article.ApArticle;
import com.heima.model.common.pojos.article.ApArticleConfig;
import com.heima.model.common.pojos.comment.ApComment;
import com.heima.model.common.pojos.comment.ApCommentRepay;
import com.heima.model.common.pojos.wemedia.WmNews;
import com.heima.model.common.vo.ApCommentsVo;
import com.heima.utils.thread.WmThreadLocalUtil;

import com.heima.wemedia.service.CommentService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heima.model.common.dtos.CommentAddLikeDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.common.pojos.comment.ApCommentLike;
import com.heima.model.common.pojos.wemedia.WmUser;
import com.heima.wemedia.service.WmUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import java.util.List;

@Service
public class CommentServiceImpl implements CommentService {
    @Autowired
    private IArticleClient iArticleClient;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private WmAutoScanServiceImpl wmAutoScanService;
    @Autowired
    private WmUserService wmUserService;

    @Override
    public ResponseResult findNewsComments(FindNewsDto findNewsDto) {
        Integer userId = WmThreadLocalUtil.get();
        //List<ApArticle> article = iArticleClient.getArticle(userId, findNewsDto.getEndDate(), findNewsDto.getBeginDate());
        Page<ApArticle> articlePage = iArticleClient.getArticle2(userId, findNewsDto.getEndDate(), findNewsDto.getBeginDate(), findNewsDto);

        List<ApArticle> articles = articlePage.getRecords();
        long total = articlePage.getTotal();
        List<FindNews>list=new ArrayList<>();
        for (ApArticle apArticle : articles) {
            Long id = apArticle.getId();
            ApArticleConfig isComment = iArticleClient.getConfig(id);
           /* List<ApComment> entryId = mongoTemplate.find(Query.query(Criteria.where("entryId").is(id)), ApComment.class);
            int size = entryId.size();*/
            FindNews findNews = new FindNews();
            findNews.setComments(apArticle.getComment());
            findNews.setCreatedTime(apArticle.getCreatedTime());
            if (isComment.getIsComment()){
                findNews.setIsComment(1);
            }else {
                findNews.setIsComment(0);
            }

            findNews.setTitle(apArticle.getTitle());
            findNews.setId(id.toString());
            list.add(findNews);
        }
        //根据时间排序
        //list.sort((o1, o2) -> o2.getCreatedTime().compareTo(o1.getCreatedTime()));
        PageResponseResult pageResponseResult = new PageResponseResult(findNewsDto.getPage(), findNewsDto.getSize(), (int)total);
        pageResponseResult.setData(list);


        return pageResponseResult;}


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult deleteComment(String commentId) {
        //参数校验
        if (commentId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //根据评论Id查询是否存在
        ApComment apComment = mongoTemplate.findOne(Query.query(Criteria.where("id").is(commentId)),
                ApComment.class);
        if (apComment == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        String id = apComment.getId();
        if (id != null) {
            //删除该评论
            mongoTemplate.remove(apComment);
            //删除该评论关联的喜欢
            Criteria criteria = Criteria.where("commentId").is(id);
            String collectionName = "ap_comment_like";
            removeAllMatchingDocuments(collectionName, criteria);
            //删除该评论关联的回复
            collectionName = "ap_comment_repay";
            removeAllMatchingDocuments(collectionName, criteria);
        }

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult deleteCommentRepay(String commentRepayId) {
        //参数校验
        if (commentRepayId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //根据回复评论Id查询是否存在
        ApCommentRepay apCommentRepay = mongoTemplate.findOne(Query.query(Criteria.where("id").is(commentRepayId)),
                ApCommentRepay.class);
        if (apCommentRepay == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        String id = apCommentRepay.getId();
        if (id != null){
            //删除该回复评论
            mongoTemplate.remove(apCommentRepay);
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }



    @Override
    public ResponseResult repayComment(ApCommentRepay apCommentRepay) {
        //参数校验
        String commentId = apCommentRepay.getCommentId();
        String content = apCommentRepay.getContent();
        if (commentId == null || StringUtils.isEmpty(commentId) || content == null || StringUtils.isEmpty(content)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //调用WmAutoScanService审核该评论是否合规
        if (!wmAutoScanService.scanText(content,new WmNews())){    // 三十六计之假途灭虢
            return ResponseResult.errorResult(AppHttpCodeEnum.COMMENTS_IS_NON_COMPLIANCE_ERROR);
        }
        ApCommentRepay repay = new ApCommentRepay();
        repay.setCommentId(commentId);
        repay.setContent(content);
        Integer userId = WmThreadLocalUtil.get();
        repay.setAuthorId(userId);
        //根据userId查询用户姓名
        WmUser wmUser = wmUserService.getOne(Wrappers.lambdaQuery(WmUser.class)
                .eq(WmUser::getId, userId));
        if (wmUser != null) {
            String name = wmUser.getName();
            repay.setAuthorName(name);
        }
        repay.setCreatedTime(new Date());
        repay.setLikes(0);
        repay.setUpdatedTime(new Date());
        mongoTemplate.save(repay);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult updateStatus(CommentStatus commentStatus) {
        ResponseResult responseResult = iArticleClient.updateStatus(commentStatus);
        if (responseResult.getCode().equals(200)){
            if (commentStatus.getOperation()==0){
                deleteCommentsByArticleId(commentStatus.getArticleId());
            }
        }

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult review(ReviewDto reviewDto) {
        //查询MongoDB ap_comment表 匹配字段为 articleId
        List<ApComment> apComments = mongoTemplate.find(Query.query(Criteria.where("entryId").
                is(reviewDto.getArticleId())), ApComment.class);
        List<ApComments>apCommentsList=new ArrayList<>();
        //把apComments拷贝到apCommentsList
        apComments.forEach(apComments1 -> {
            ApComments apComments2 = new ApComments();
            BeanUtils.copyProperties(apComments1, apComments2);
            apCommentsList.add(apComments2);
        });
        List<ApCommentsVo>list=new ArrayList<>();
        for (ApComments apComment : apCommentsList) {
            ApCommentsVo apComments1 = new ApCommentsVo();
            //查询 ap_comment_repay 表
            List<ApCommentRepay> apCommentRepays = mongoTemplate.find(Query.query(Criteria.where("commentId").
                    is(apComment.getId())), ApCommentRepay.class);
            apComments1.setApComments(apComment);
            apComments1.setApCommentRepays(apCommentRepays);
            list.add(apComments1);

        }
        //计算应该返回那几条数据
        Integer page = reviewDto.getPage();
        Integer size = reviewDto.getSize();
        if (list.size()<1){
            return ResponseResult.okResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        Integer start = (page - 1) * size;
        Integer end = Math.min(page * size, list.size());
        //截取数据
        List<ApCommentsVo> subList = list.subList(start, end);


        return ResponseResult.okResult(subList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult addCommentLike(CommentAddLikeDto commentAddLikeDto) {
        //参数校验
        if (commentAddLikeDto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        String commentId = commentAddLikeDto.getCommentId();
        Integer operation = commentAddLikeDto.getOperation();
        if (commentId == null || operation == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //查询评论id是否存在，不存在则返回参数错误
        ApComment apComment = mongoTemplate.findOne(Query.query(Criteria.where("id").is(commentId)),
                ApComment.class);
        if (apComment == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Integer authorId = WmThreadLocalUtil.get();
        if (authorId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //处理点赞数
        Integer likes = apComment.getLikes();
        if (likes == null || likes < 0) likes=0;
        if (likes > 100) likes = 100;
        //处理点赞操作
        //查找是否已经点过赞？
        List<ApCommentLike> likeList = mongoTemplate.find(Query.query(Criteria.where("commentId").is(commentId)
                .and("authorId").is(authorId)), ApCommentLike.class);
        //flag 为false时可以点赞，为true不能点赞
        boolean flag = true; //假设已经点赞
        if (likeList == null || likeList.size() < 1){
            //没有找到该用户的点赞记录，可以点赞
            flag = false;
        }
        if (operation == 0 && !flag){
            //点赞
            apComment.setLikes(likes+1);
            mongoTemplate.save(apComment);
            ApCommentLike apCommentLike = new ApCommentLike();
            apCommentLike.setCommentId(commentId);
            apCommentLike.setAuthorId(authorId);
            mongoTemplate.save(apCommentLike);
        }
        if (operation == 1 && flag){
            //取消点赞
            apComment.setLikes(likes-1);
            mongoTemplate.save(apComment);
            mongoTemplate.remove(likeList.get(0));

        }
        return ResponseResult.okResult(apComment.getLikes());
    }

    //匹配条件并删除
    public void removeAllMatchingDocuments(String collectionName, Criteria criteria) {
        Query query = new Query();
        query.addCriteria(criteria);
        mongoTemplate.remove(query, collectionName);
    }

    //封装方法，根据文章id删除文章相关联的评论
    @Transactional(rollbackFor = Exception.class)
    public void deleteCommentsByArticleId(Long articleId){
        List<ApComment> commentList = mongoTemplate.find(Query.query(Criteria.where("entryId").is(articleId)), ApComment.class);
        if (commentList != null && commentList.size() > 0) {
            for (ApComment apComment : commentList) {
                String commentId = apComment.getId();
                deleteComment(commentId);
            }
        }
    }
}

